from flask import Blueprint, render_template, jsonify, request, send_file
import os
import sys
from pathlib import Path
import pandas as pd
from personnel_network_analysis import main as generate_analysis
import numpy as np
import traceback
from io import BytesIO

# 创建Blueprint
personnel_network_bp = Blueprint('personnel_network', __name__)

def get_resource_path(relative_path):
    """获取资源文件的绝对路径，支持开发环境和打包环境"""
    if hasattr(sys, '_MEIPASS'):
        # PyInstaller 打包环境
        base_path = sys._MEIPASS
    else:
        # 开发环境
        base_path = os.path.dirname(os.path.abspath(__file__))
    
    return os.path.join(base_path, relative_path)

# 配置数据文件路径
DATA_DIR = Path("data")
SOURCE_DIR = DATA_DIR / "source"
OUTPUT_DIR = DATA_DIR / "output"

# 确保目录存在
SOURCE_DIR.mkdir(parents=True, exist_ok=True)
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

@personnel_network_bp.route('/personnel-network')
def personnel_network():
    """渲染人员关系网络分析页面"""
    return render_template('pages/personnel_network.html', active_page='personnel_network')

@personnel_network_bp.route('/personnel-network/get-folders')
def get_folders():
    """获取source目录下的所有文件夹"""
    try:
        # 确保目录存在
        if not SOURCE_DIR.exists():
            SOURCE_DIR.mkdir(parents=True, exist_ok=True)
            return jsonify({'folders': []})

        # 获取所有文件夹
        folders = [f.name for f in SOURCE_DIR.iterdir() if f.is_dir()]
        return jsonify({'folders': folders})

    except Exception as e:
        return jsonify({'error': str(e)}), 500

@personnel_network_bp.route('/personnel-network/check-analysis-results')
def check_analysis_results():
    """检查每个文件夹的分析结果是否存在"""
    try:
        results = {}
        all_complete = True
        
        # 确保output目录存在
        if not OUTPUT_DIR.exists():
            OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
            return jsonify({'results': results, 'all_complete': False})
        
        # 获取source目录下的所有文件夹
        source_folders = [f.name for f in SOURCE_DIR.iterdir() if f.is_dir()]
        
        # 需要检查的文件列表
        required_files = ["交易明细.xlsx", "交易汇总.xlsx", "关系总表.xlsx"]
        
        # 检查每个文件夹对应的output目录中是否存在所有必需的文件
        for folder in source_folders:
            output_folder = OUTPUT_DIR / folder
            folder_complete = True
            
            # 检查每个必需文件是否存在
            for file_name in required_files:
                if not (output_folder / file_name).exists():
                    folder_complete = False
                    break
            
            results[folder] = folder_complete
            if not folder_complete:
                all_complete = False
        
        return jsonify({
            'results': results,
            'all_complete': all_complete
        })
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@personnel_network_bp.route('/personnel-network/generate-analysis', methods=['POST'])
def generate_network_analysis():
    """生成人员关系网络分析结果"""
    try:
        # 调用分析函数生成结果
        generate_analysis()
        return jsonify({'success': True})
        
    except Exception as e:
        print(f"生成分析结果时出错: {str(e)}")  # 打印错误信息
        return jsonify({
            'success': False,
            'error': f'生成分析结果时出错: {str(e)}'
        }) 

@personnel_network_bp.route('/personnel-network/get-analysis-data')
def get_analysis_data():
    """获取所有分析结果数据"""
    try:
        data_type = request.args.get('type', 'detail')  # 默认为明细数据
        all_data = []
        
        # 获取筛选条件
        selected_folders = request.args.getlist('folders')  # 选择的文件夹
        relationship_types = request.args.getlist('relationshipTypes')  # 关系类型
        name_filter = request.args.get('nameFilter')  # 名称筛选
        
        # 关系类型映射
        relationship_mapping = {
            'relative': '亲属',
            'business': '三商清单',
            'specific': '特定关系人',
            'company': '任职单位'
        }
        
        # 转换关系类型
        filtered_relationship_types = [relationship_mapping[rt] for rt in relationship_types if rt in relationship_mapping]
        
        # 获取所有output文件夹
        if not OUTPUT_DIR.exists():
            return jsonify({'error': '暂无分析数据'})
            
        # 遍历output目录下的所有文件夹
        for folder in OUTPUT_DIR.iterdir():
            if folder.is_dir():
                # 如果选择了文件夹且当前文件夹不在选择中，则跳过
                if selected_folders and folder.name not in selected_folders:
                    continue
                    
                # 根据类型选择不同的文件
                file_name = "交易汇总.xlsx" if data_type == 'summary' else "交易明细.xlsx"
                result_file = folder / file_name
                
                if result_file.exists():
                    try:
                        # 读取Excel文件
                        df = pd.read_excel(result_file, engine='openpyxl')
                        # 添加文件夹名称列
                        if '文件夹' not in df.columns:
                            df['文件夹'] = folder.name
                            
                        # 应用关系类型筛选
                        if filtered_relationship_types:
                            df = df[df['关系类型'].isin(filtered_relationship_types)]

                        # 应用名称筛选（同时匹配名称和交易对方名称）
                        if name_filter:
                            df = df[(df['名称'] == name_filter) | (df['交易对方名称'] == name_filter)]
                            
                        if not df.empty:
                            all_data.append(df)
                    except Exception as e:
                        print(f"读取文件 {result_file} 时出错: {str(e)}")
                        continue
        
        if not all_data:
            return jsonify({'error': f'未找到{file_name}数据'})
            
        # 合并所有数据
        combined_df = pd.concat(all_data, ignore_index=True)
        
        # 获取所有列名
        columns = combined_df.columns.tolist()

        # 获取选择的字段
        selected_fields = request.args.getlist('fields')
        if selected_fields:
            # 确保所有请求的字段都存在
            valid_fields = [field for field in selected_fields if field in columns]
            if valid_fields:
                combined_df = combined_df[valid_fields]
            else:
                return jsonify({'error': '没有找到有效的字段'})
        
        # 转换数据为字典列表
        data = combined_df.to_dict('records')
        
        # 处理数据中的特殊值（NaN等）
        for record in data:
            for key, value in record.items():
                if pd.isna(value):
                    record[key] = None
                elif isinstance(value, (pd.Timestamp, pd.DatetimeTZDtype)):
                    record[key] = value.isoformat()
                elif isinstance(value, (np.int64, np.float64)):
                    record[key] = float(value) if isinstance(value, np.float64) else int(value)
        
        return jsonify({
            'success': True,
            'data': data,
            'columns': columns,
            'total_records': len(data)
        })
        
    except Exception as e:
        print(f"获取数据时出错: {str(e)}")  # 打印错误信息以便调试
        traceback.print_exc()  # 打印完整的错误堆栈
        return jsonify({
            'error': f'获取数据时出错: {str(e)}'
        }), 500

@personnel_network_bp.route('/personnel-network/download-excel')
def download_excel():
    """下载人员关系网络分析结果"""
    try:
        data_type = request.args.get('type', 'detail')  # 默认为明细数据
        all_data = []
        
        # 获取筛选条件
        selected_folders = request.args.getlist('folders')  # 选择的文件夹
        relationship_types = request.args.getlist('relationshipTypes')  # 关系类型
        name_filter = request.args.get('nameFilter')  # 名称筛选
        
        # 关系类型映射
        relationship_mapping = {
            'relative': '亲属',
            'business': '三商清单',
            'specific': '特定关系人',
            'company': '任职单位'
        }
        
        # 转换关系类型
        filtered_relationship_types = [relationship_mapping[rt] for rt in relationship_types if rt in relationship_mapping]
        
        # 遍历output目录下的所有文件夹
        for folder in OUTPUT_DIR.iterdir():
            if folder.is_dir():
                # 如果选择了文件夹且当前文件夹不在选择中，则跳过
                if selected_folders and folder.name not in selected_folders:
                    continue
                    
                # 根据类型选择不同的文件
                file_name = "交易汇总.xlsx" if data_type == 'summary' else "交易明细.xlsx"
                result_file = folder / file_name
                
                if result_file.exists():
                    try:
                        # 读取Excel文件
                        df = pd.read_excel(result_file, engine='openpyxl')
                        # 添加文件夹名称列
                        if '文件夹' not in df.columns:
                            df['文件夹'] = folder.name
                            
                        # 应用关系类型筛选
                        if filtered_relationship_types:
                            df = df[df['关系类型'].isin(filtered_relationship_types)]

                        # 应用名称筛选（同时匹配名称和交易对方名称）
                        if name_filter:
                            df = df[(df['名称'] == name_filter) | (df['交易对方名称'] == name_filter)]
                            
                        if not df.empty:
                            all_data.append(df)
                    except Exception as e:
                        print(f"读取文件 {result_file} 时出错: {str(e)}")
                        continue

        if not all_data:
            return jsonify({'error': f'分析结果文件不存在'}), 404

        # 合并所有数据
        combined_df = pd.concat(all_data, ignore_index=True)
        
        # 获取选择的字段
        selected_fields = request.args.getlist('fields')
        if selected_fields:
            # 确保所有请求的字段都存在
            valid_fields = [field for field in selected_fields if field in combined_df.columns]
            if not valid_fields:
                return jsonify({'error': '没有找到有效的字段'}), 400
            combined_df = combined_df[valid_fields]

        # 如果数据为空，返回错误
        if combined_df.empty:
            return jsonify({'error': '筛选后没有符合条件的数据'}), 400

        # 创建文件名
        filename = "人员关系网络交易汇总.xlsx" if data_type == 'summary' else "人员关系网络交易明细.xlsx"
        
        # 使用BytesIO直接在内存中处理Excel文件
        excel_buffer = BytesIO()
        
        # 直接写入内存流
        with pd.ExcelWriter(excel_buffer, engine='openpyxl') as writer:
            combined_df.to_excel(writer, index=False)
        
        # 将指针移到开始位置
        excel_buffer.seek(0)
        
        return send_file(
            excel_buffer,
            as_attachment=True,
            download_name=filename,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )

    except Exception as e:
        return jsonify({
            'error': f'下载文件时出错: {str(e)}'
        }), 500